/***********************************************************************************
Copy right:	    hqyj Tech.
Author:         jiaoyue
Date:           2023.07.01
Description:    http请求处理
***********************************************************************************/

#include <sys/types.h>
#include <sys/socket.h>
#include "custom_handle.h"
#include "shmem.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <semaphore.h>
#include <sqlite3.h>
#include "cJSON.h"
#include <sys/mman.h>
#include <fcntl.h>
#define SHARED_MEM_NAME "point_table_shm"
#define SEM_NAME "/point_table_shm_sem"
// 数据类型定义
typedef enum
{
    TYPE_BOOL = 1,  // 布尔类型
    TYPE_INT = 2,   // 整数类型
    TYPE_FLOAT = 3, // 浮点类型
} DataType;

// STM32设备点表项
typedef struct
{
    uint16_t key;   // 点表键值
    char name[32];  // 点表名称
    DataType type;  // 数据类型
    uint8_t status; // 状态标志(0=无效,1=有效)
    union
    {
        int int_value;
        float float_value;
        int bool_value;
    } value;
} STM32Item;

// Modbus设备点表项
typedef struct
{
    uint16_t key;   // 点表键值
    char name[32];  // 点表名称
    uint16_t addr;  // Modbus地址
    DataType type;  // 数据类型
    uint8_t status; // 状态标志(0=无效,1=有效)
    union
    {
        int int_value;
        float float_value;
        int bool_value;
    } value;
} ModbusItem;

// 完整配置结构体
typedef struct
{
    int stm32_count;            // STM32点表项数量
    STM32Item stm32_items[100]; // 与写入程序保持一致

    int modbus_count;             // Modbus点表项数量
    ModbusItem modbus_items[100]; // 与写入程序保持一致

    // 其他配置信息
    char version[10]; // 配置版本
    struct
    {
        int type;   // 报告类型
        int period; // 报告周期
    } report;
    struct
    {
        char addr[20]; // MQTT服务器地址
        int port;      // MQTT服务器端口
    } mqtt_server;
    struct
    {
        char addr[20]; // Modbus设备地址
        int port;      // Modbus设备端口
    } mb_dev;
    struct
    {
        char addr[20]; // Modbus应用地址
        int port;      // Modbus应用端口
    } mb_app;
} ConfigData;
ConfigData *config = NULL;
struct msgbuf // 消息队列
{
    long mtype; // 第一个成员必须是long类型变量，表示消息的类型
    int key;
    int value;
};
struct msgbuf msg;
key_t key;
#define MSG_PATH "/tmp/ipc/msgqueue/peer/" // 消息队列路径
#define MAGIC_ID 'j'

sqlite3 *db;
char *errmsg;
char sql[1024];

#define KB 1024
#define HTML_SIZE (64 * KB)

// 普通的文本回复需要增加html头部
#define HTML_HEAD "Content-Type: text/html\r\n" \
                  "Connection: close\r\n"

static int handle_login(int sock, const char *input) // 登录处理
{
    char reply_buf[HTML_SIZE] = {0};
    char *uname = strstr(input, "username=");
    uname += strlen("username=");
    char *p = strstr(input, "password");
    *(p - 1) = '\0';
    printf("username = %s\n", uname);

    char *passwd = p + strlen("password=");
    printf("passwd = %s\n", passwd);

    sprintf(sql, "select * from user where username = '%s' and password = '%s';", uname, passwd);
    printf("%s\n", sql);
    char **result = NULL;
    int row = 0, column = 0;
    sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
    printf("%d\n", row);
    if (row == 0) // 用户名或密码错误
    {
        printf("登录失败，用户名或密码错误\n");
        //"用户名或密码错误"提示，chrome浏览器直接输送utf-8字符流乱码，没有找到太好解决方案，先过渡
        char out1[128] = {0xd3, 0xc3, 0xbb, 0xa7, 0xc3, 0xfb, 0xbb, 0xf2, 0xc3, 0xdc, 0xc2, 0xeb, 0xb4, 0xed, 0xce, 0xf3}; // “用户名或密码错误”的 GB2312 编码
        sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out1);                                        // 用于弹出一个提示框，显示“用户名或密码错误”。
        strcat(reply_buf, "<script>window.location.href = '/login2.0.html';</script>");                                    // 将浏览器重定向到登录页面
        send(sock, reply_buf, strlen(reply_buf), 0);                                                                       // 将 reply_buf 中的内容发送给客户端
    }
    else // 登录成功
    {
        printf("登录成功\n");
        sprintf(reply_buf, "<script>localStorage.setItem('usr_user_name', '%s');</script>", uname); // 在客户端的本地存储中存储用户名
        strcat(reply_buf, "<script>window.location.href = '/mainpage.html';</script>");             // 将浏览器重定向到项目页面
        send(sock, reply_buf, strlen(reply_buf), 0);                                                //**发送消息
    }
    // sqlite3_free_table(result);
    //  if (strcmp(uname, "admin") == 0 && strcmp(passwd, "admin") == 0)

    return 0;
}

//****************************************************************************************
static int handle_register(int sock, const char *input) // 将注册的用户名和密码写入数据库中
{
    char reply_buf[HTML_SIZE] = {0};           //**定义回复缓冲区
    char *uname = strstr(input, "username1="); //**查找用户名
    uname += strlen("username1=");             //**跳过"username1="
    char *p = strstr(input, "password1");      //**查找密码
    *(p - 1) = '\0';                           //**将密码结尾'\0'
    printf("username = %s\n", uname);          //**打印用户名
    char *passwd = p + strlen("password1=");   //**跳过"password1="
    printf("passwd = %s\n", passwd);           //**打印密码

    // 检查用户名是否已存在
    sprintf(sql, "select * from user where username = '%s';", uname); //**构造查询语句
    char **result = NULL;                                             //**定义查询结果
    int row = 0, column = 0;                                          //**定义查询结果行数和列数
    sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);      //**执行查询语句
    if (row > 0)                                                      // 用户名已存在
    {
        printf("注册失败: 用户名已存在\n"); //**打印错误信息
        //"用户名已存在"提示，chrome浏览器直接输送utf-8字符流乱码，没有找到太好解决方案，先过渡
        char out2[128] = {0xd3, 0xc3, 0xbb, 0xa7, 0xc3, 0xfb, 0xd2, 0xd1, 0xb4, 0xe6, 0xd4, 0xda, 0x00};
        sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out2);
        strcat(reply_buf, "<script>window.location.href = '/register.html';</script>"); // 跳转到注册页面
        send(sock, reply_buf, strlen(reply_buf), 0);                                    //**发送消息
        sqlite3_free_table(result);                                                     //**释放查询结果
        return -1;
    }
    else // 用户名不存在，可以注册
    {
        sprintf(sql, "insert into user values('%s','%s');", uname, passwd); //**构造插入语句
        printf("%s\n", sql);                                                //**打印插入语句
        if (sqlite3_exec(db, sql, NULL, NULL, &errmsg))                     //**执行插入语句
        {
            fprintf(stderr, "insert err:%s\n", errmsg); //**打印错误信息
            sqlite3_free(errmsg);                       //**释放错误信息
            printf("web register failed\n");            //**打印错误信息
            // 注册失败提示
            char out3[128] = {0xd7, 0xa2, 0xb2, 0xe1, 0xca, 0xa7, 0xb0, 0xdc, 0x00};        //**定义错误信息
            sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out3);     //**将错误信息存入回复缓冲区
            strcat(reply_buf, "<script>window.location.href = '/register.html';</script>"); //**跳转到注册页面
            send(sock, reply_buf, strlen(reply_buf), 0);                                    //**发送消息
            sqlite3_free_table(result);                                                     //**释放查询结果
            return -1;
        }
        else
        {
            printf("注册成功");
            // 注册成功提示并跳转到登录页面
            char out4[128] = {0xd7, 0xa2, 0xb2, 0xe1, 0xb3, 0xc9, 0xb9, 0xa6, 0x00};        //**定义成功信息
            sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out4);     //**将成功信息存入回复缓冲区
            strcat(reply_buf, "<script>window.location.href = '/login2.0.html';</script>"); //**跳转到登录页面
            send(sock, reply_buf, strlen(reply_buf), 0);                                    //**发送消息
        }
    }
    sqlite3_free_table(result);

    return 0;
}
static int handle_forgetpasswd(int sock, const char *input) // 将注册的用户名和密码写入数据库中
{
    char reply_buf[HTML_SIZE] = {0};           //**定义回复缓冲区
    char *uname = strstr(input, "username2="); //**查找用户名
    uname += strlen("username2=");             //**跳过"username2="
    char *p = strstr(input, "password2");      //**查找密码
    *(p - 1) = '\0';                           //**将密码结尾'\0'
    printf("username = %s\n", uname);          //**打印用户名
    char *passwd = p + strlen("password2=");   //**跳过"password2="
    printf("passwd = %s\n", passwd);           //**打印密码

    // 检查用户名是否已存在
    sprintf(sql, "select * from user where username = '%s';", uname); //**构造查询语句
    char **result = NULL;                                             //**定义查询结果
    int row = 0, column = 0;                                          //**定义查询结果行数和列数
    sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);      //**执行查询语句
    if (row > 0)                                                      // 用户名已存在
    {
        // 存在则更新密码
        sprintf(sql, "update user set password = '%s' where username = '%s';", passwd, uname); //**构造更新语句
        if (sqlite3_exec(db, sql, NULL, NULL, &errmsg))
        {
            fprintf(stderr, "update err:%s\n", errmsg);
            printf("密码更新失败");
        }
        else
        {
            printf("密码更新成功");
            //"用户名已存在"提示，chrome浏览器直接输送utf-8字符流乱码，没有找到太好解决方案，先过渡
            char out2[128] = {0xd0, 0xde, 0xb8, 0xc4, 0xb3, 0xc9, 0xb9, 0xa6, 0x00}; // 修改成功
            sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out2);
            strcat(reply_buf, "<script>window.location.href = '/login2.0.html';</script>"); // 跳转到登录页面
            send(sock, reply_buf, strlen(reply_buf), 0);                                    //**发送消息
        }
    }
    else // 用户名不存在，先去注册
    {
        char out3[128] = {0xd3, 0xc3, 0xbb, 0xa7, 0xc3, 0xfb, 0xb2, 0xbb,               // "用户名不"
                          0xb4, 0xe6, 0xd4, 0xda, 0xa3, 0xac, 0xc7, 0xeb,               // "存在，请"
                          0xcf, 0xc8, 0xd7, 0xa2, 0xb2, 0xe1, 0x00};                    // "先注册"
        sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out3);     //**将错误信息存入回复缓冲区
        strcat(reply_buf, "<script>window.location.href = '/register.html';</script>"); //**跳转到注册页面
        send(sock, reply_buf, strlen(reply_buf), 0);                                    //**发送消息
        sqlite3_free_table(result);                                                     //**释放查询结果
        return -1;
    }
    sqlite3_free_table(result);
    return 0;
}
//***************************************************************************************
// handle_write函数只负责写入消息队列
static int handle_write(int sock, cJSON *request)
{
    key_t key;
    int ret;
    int msgid;
    char sys_cmd[256];
    char path[256];
    sprintf(path, "%s%s", MSG_PATH, "stm32");
    //文件不存在创建
    if(access(path, F_OK) < 0)
    {
        sprintf(sys_cmd, "%s %s", "mkdir -p", path);
        ret = system(sys_cmd);
        UNUSED(ret);
    }
    //创建key
    key = ftok(path, MAGIC_ID);
    if(key < 0){
        perror("fail to ftok");
        return -1;
    }
    //创建消息队列
    msgid = msgget(key, IPC_CREAT|0666);
    if (msgid < 0)
    {
        perror("fail to msgget");
        return -1;
    }
    // 解析请求参数
    cJSON *sensors = cJSON_GetObjectItem(request, "sensors");   // 获取"sensors"数组
    cJSON *values = cJSON_GetObjectItem(request, "values");

    if (!cJSON_IsArray(sensors) || !cJSON_IsArray(values) ||
        cJSON_GetArraySize(sensors) != cJSON_GetArraySize(values))
    {
        const char *err = "{\"error\":\"Invalid write format\"}";
        send(sock, err, strlen(err), 0);
        return -1;
    }

    // 创建消息队列连接
    msgid = msgget(key, 0666 | IPC_CREAT);
    if (msgid == -1)
    {
        perror("msgget failed");
        return -1;
    }

    // 发送每条指令到消息队列
    for (int i = 0; i < cJSON_GetArraySize(sensors); i++)
    {

        struct msg_buf
        {
            long mtype;
            int key;
            int value;
        } msg;
        msg.mtype = 1;                                      // 固定消息类型
        msg.key = cJSON_GetArrayItem(sensors, i)->valueint; // 从JSON中获取键值
        msg.value = cJSON_GetArrayItem(values, i)->valueint;

        if (msgsnd(msgid, &msg, sizeof(msg) - sizeof(long), 0) == -1) // 发送消息到消息队列
        {
            perror("msgsnd failed");
            continue;
        }
        printf("Sent to queue: key=%d value=%d\n", msg.key, msg.value);
    }

    const char *success = "{\"status\":\"queued\"}";
    send(sock, success, strlen(success), 0);
    return 0;
}

static int handle_read(int sock, const char *input) // 读取共享内存------------------------------------------------------
{
    struct shm_param shm;
    sem_t *shm_sem;
    // 打开信号量
    shm_sem = sem_open(SEM_NAME, 0);
    if (shm_sem == SEM_FAILED)
    {
        perror("Failed to open semaphore");
        return 1;
    }
    // 计算共享内存所需大小
    const size_t SHARED_MEM_SIZE = sizeof(ConfigData);
    printf("ConfigData size: %zu bytes\n", SHARED_MEM_SIZE);

    // 初始化共享内存（这里只是获取信息，不会重新创建共享内存）
    if (shm_init(&shm, SHARED_MEM_NAME, SHARED_MEM_SIZE, 0) != 0)
    {
        fprintf(stderr, "Failed to initialize shared memory\n");
        sem_close(shm_sem);
        return 1;
    }
    // 获取共享内存地址
    void *shm_addr = shm_getaddr(&shm);
    if (shm_addr == NULL)
    {
        fprintf(stderr, "Failed to attach shared memory\n");
        sem_close(shm_sem);
        return 1;
    }
    // 加锁读取共享内存
    sem_wait(shm_sem);
    // 将共享内存地址转换为ConfigData结构体指针
    ConfigData *config = (ConfigData *)shm_addr; // 确保类型匹配
    // 解锁
    sem_post(shm_sem);
    // 构建json数据
    cJSON *root = cJSON_CreateObject();  // 创建一个JSON对象，用于存储配置信息
    cJSON *modbus = cJSON_CreateArray(); // 创建一个数组用于存储Modbus项
    cJSON *stm32 = cJSON_CreateArray();  // 创建一个数组用于存储STM32项
    // 打印STM32点表项
    for (int i = 0; i < config->stm32_count && i < 100; i++)
    {
        cJSON *item = cJSON_CreateObject();                                     // 创建一个对象用于存储STM32项的信息
        cJSON_AddNumberToObject(item, "key", config->stm32_items[i].key);       // 添加键值对
        cJSON_AddStringToObject(item, "name", config->stm32_items[i].name);     // 添加键值对
        cJSON_AddNumberToObject(item, "type", config->stm32_items[i].type);     // 添加键值对
        cJSON_AddNumberToObject(item, "status", config->stm32_items[i].status); // 添加键值对
        // 根据type打印对应的值
        switch (config->stm32_items[i].type)
        {
        case TYPE_BOOL:
            cJSON_AddBoolToObject(item, "value", config->stm32_items[i].value.bool_value); // 添加键值对
            break;
        case TYPE_INT:
            cJSON_AddNumberToObject(item, "value", config->stm32_items[i].value.int_value); // 添加键值对
            break;
        case TYPE_FLOAT:
            cJSON_AddNumberToObject(item, "value", config->stm32_items[i].value.float_value); // 添加键值对
            break;
        default:
            cJSON_AddStringToObject(item, "value", "[invalid type]"); // 添加键值对
            break;
        }
        cJSON_AddItemToArray(stm32, item); // 将STM32项添加到数组中
    }
    cJSON_AddItemToObject(root, "stm32", stm32); // 将STM32数组添加到根对象中
    // 打印Modbus点表项
    for (int i = 0; i < config->modbus_count && i < 100; i++)
    {
        cJSON *item = cJSON_CreateObject();                                      // 创建一个对象用于存储Modbus项的信息
        cJSON_AddNumberToObject(item, "key", config->modbus_items[i].key);       // 添加键值对
        cJSON_AddStringToObject(item, "name", config->modbus_items[i].name);     // 添加键值对
        cJSON_AddNumberToObject(item, "addr", config->modbus_items[i].addr);     // 添加键值对
        cJSON_AddNumberToObject(item, "type", config->modbus_items[i].type);     // 添加键值对
        cJSON_AddNumberToObject(item, "status", config->modbus_items[i].status); // 添加键值对
        // 根据type打印对应的值
        switch (config->modbus_items[i].type)
        {
        case TYPE_BOOL:
            cJSON_AddBoolToObject(item, "value", config->modbus_items[i].value.bool_value); // 添加键值对
            break;
        case TYPE_INT:
            cJSON_AddNumberToObject(item, "value", config->modbus_items[i].value.int_value); // 添加键值对
            break;
        case TYPE_FLOAT:
            cJSON_AddNumberToObject(item, "value", config->modbus_items[i].value.float_value); // 添加键值对
            break;
        default:
            cJSON_AddStringToObject(item, "value", "[invalid type]"); // 添加键值对
            break;
        }
        cJSON_AddItemToArray(modbus, item); // 将Modbus项添加到数组中
    }
    cJSON_AddItemToObject(root, "modbus", modbus);      // 将Modbus数组添加到根对象中
    char *json_response = cJSON_PrintUnformatted(root); // 将JSON对象转换为字符串
    printf("json_response = %s\n", json_response);
    send(sock, json_response, strlen(json_response), 0); // 发送JSON响应给网页不能不写
    // 释放内存
    // cJSON_Delete(root);
    // free(json_response);
    // 关闭信号量
    sem_close(shm_sem);
    return 0;
}

static int handle_read_filtered(int sock, cJSON *request)   // 读取共享内存
{
    struct shm_param shm;
    sem_t *shm_sem;

    // 打开信号量
    if ((shm_sem = sem_open(SEM_NAME, 0)) == SEM_FAILED)
    {
        perror("sem_open failed");
        return 1;
    }

    // 初始化共享内存
    if (shm_init(&shm, SHARED_MEM_NAME, sizeof(ConfigData), 0) != 0)
    {
        fprintf(stderr, "共享内存初始化失败\n");
        sem_close(shm_sem);
        return 1;
    }

    ConfigData *config = (ConfigData *)shm_getaddr(&shm);
    if (!config)
    {
        fprintf(stderr, "共享内存附加失败\n");
        sem_close(shm_sem);
        return 1;
    }
    // 加锁读取
    sem_wait(shm_sem);

    cJSON *response = cJSON_CreateObject();
    cJSON *valuesArray = cJSON_CreateArray();
    cJSON *statusArray = cJSON_CreateArray();

    // 解析请求参数
    cJSON *valuesReq = cJSON_GetObjectItem(request, "values");
    cJSON *statusReq = cJSON_GetObjectItem(request, "status");
    //处理modbus请求（201-203）
    if (valuesReq && cJSON_IsArray(valuesReq))
    {
        for (int i = 0; i < cJSON_GetArraySize(valuesReq); i++)
        {
            int key = cJSON_GetArrayItem(valuesReq, i)->valueint;
            for (int j = 0; j < config->modbus_count; j++)
            {
                if (config->modbus_items[j].key == key)
                {
                    cJSON *item = cJSON_CreateObject();
                    cJSON_AddNumberToObject(item, "key", key);
                    // 根据数据类型添加值
                    switch (config->modbus_items[j].type)
                    {
                    case TYPE_FLOAT:
                        cJSON_AddNumberToObject(item, "value",
                                                config->modbus_items[j].value.float_value);
                        break; 
                    case TYPE_INT:
                        cJSON_AddNumberToObject(item, "value",
                                                config->modbus_items[j].value.int_value);
                        break;
                    default:
                        cJSON_AddNullToObject(item, "value");

                    } 
                    cJSON_AddItemToArray(valuesArray, item);
                    break;

                } 

            } 

        } 

    }
    // 处理数值请求（101-102）
    if (valuesReq && cJSON_IsArray(valuesReq))
    {
        for (int i = 0; i < cJSON_GetArraySize(valuesReq); i++)
        {
            int key = cJSON_GetArrayItem(valuesReq, i)->valueint;
            for (int j = 0; j < config->stm32_count; j++)
            {
                if (config->stm32_items[j].key == key)
                {
                    cJSON *item = cJSON_CreateObject();
                    cJSON_AddNumberToObject(item, "key", key);
                    // 根据数据类型添加值
                    switch (config->stm32_items[j].type)
                    {
                    case TYPE_FLOAT:
                        cJSON_AddNumberToObject(item, "value",
                                                config->stm32_items[j].value.float_value);
                        break;
                    case TYPE_INT:
                        cJSON_AddNumberToObject(item, "value",
                                                config->stm32_items[j].value.int_value);
                        break;
                    default:
                        cJSON_AddNullToObject(item, "value");
                    }
                    cJSON_AddItemToArray(valuesArray, item);
                    break;
                }
            }
        }
    }

    // 处理状态请求（103-110）
    if (statusReq && cJSON_IsArray(statusReq))
    {
        for (int i = 0; i < cJSON_GetArraySize(statusReq); i++)
        {
            int key = cJSON_GetArrayItem(statusReq, i)->valueint;
            for (int j = 0; j < config->stm32_count; j++)
            {
                if (config->stm32_items[j].key == key)
                {
                    cJSON *item = cJSON_CreateObject();
                    cJSON_AddNumberToObject(item, "key", key);
                    cJSON_AddNumberToObject(item, "status",
                                            config->stm32_items[j].status);
                    cJSON_AddItemToArray(statusArray, item);
                    break;
                }
            }
        }
    }

    sem_post(shm_sem);
    sem_close(shm_sem);

    // 构建响应
    cJSON_AddItemToObject(response, "values", valuesArray);
    cJSON_AddItemToObject(response, "status", statusArray);

    char *json_str = cJSON_PrintUnformatted(response);
    send(sock, json_str, strlen(json_str), 0);

    cJSON_Delete(response);
    free(json_str);
    return 0;
}

/**
 * @brief 处理自定义请求，在这里添加进程通信
 * @param input
 * @return
 */
int parse_and_process(int sock, const char *query_string, const char *input)
{
    // 先处理登录操作
    if (strstr(input, "username=") && strstr(input, "password="))
    {
        return handle_login(sock, input);
    }
    // 处理注册操作
    if (strstr(input, "username1=") && strstr(input, "password1="))
    {
        return handle_register(sock, input);
    }
    // 忘记密码操作
    if (strstr(input, "username2=") && strstr(input, "password2="))
    {
        return handle_forgetpasswd(sock, input);
    }
    else // JSON请求处理
    {

        cJSON *root = cJSON_Parse(input);
        if (!root)
        {
            const char *err = "{\"error\":\"Invalid JSON\"}";
            send(sock, err, strlen(err), 0);
            return -1;
        }

        cJSON *action = cJSON_GetObjectItem(root, "action");
        if (!action || !cJSON_IsString(action))
        {
            cJSON_Delete(root);
            const char *err = "{\"error\":\"Missing action\"}";
            send(sock, err, strlen(err), 0);
            return -1;
        }

        if (strcmp(action->valuestring, "read") == 0)      // 如果action字段的值为"read"
        {
                // 默认读取全部
                handle_read(sock, input);
         
        }
        else if (strcmp(action->valuestring, "write") == 0)
        {
            cJSON *sensors = cJSON_GetObjectItem(root, "sensors");
            cJSON *values = cJSON_GetObjectItem(root, "values");

            if (!sensors || !cJSON_IsArray(sensors) ||
                !values || !cJSON_IsArray(values) ||
                cJSON_GetArraySize(sensors) != cJSON_GetArraySize(values))
            {
                const char *error_response = "{\"error\":\"Invalid write format\"}";
                send(sock, error_response, strlen(error_response), 0);
                cJSON_Delete(root);
                return -1;
            }

            // 遍历所有要写入的传感器
            for (int i = 0; i < cJSON_GetArraySize(sensors); i++)
            {
                cJSON *sensor_item = cJSON_GetArrayItem(sensors, i);
                cJSON *value_item = cJSON_GetArrayItem(values, i);

                if (!cJSON_IsNumber(sensor_item) || !cJSON_IsNumber(value_item))
                    continue;

                int key = sensor_item->valueint;  // 假设key是整数
                int value = value_item->valueint; // 假设value是整数

                // 调用修改后的handle_write函数
                handle_write(sock, root);
            }

            const char *success_response = "{\"status\":\"success\"}";
            send(sock, success_response, strlen(success_response), 0);
        }

        cJSON_Delete(root);
    }
    return 0;
}
